home *** CD-ROM | disk | FTP | other *** search
/ Total Network Tools 2002 / NextStepPublishing-TotalNetworkTools2002-Win95.iso / Archive / Misc Servers / Zope.exe / ZOPESECURITYPOLICY.PY < prev    next >
Encoding:
Python Source  |  2000-07-05  |  9.3 KB  |  233 lines

  1. ##############################################################################
  2. # Zope Public License (ZPL) Version 1.0
  3. # -------------------------------------
  4. # Copyright (c) Digital Creations.  All rights reserved.
  5. # This license has been certified as Open Source(tm).
  6. # Redistribution and use in source and binary forms, with or without
  7. # modification, are permitted provided that the following conditions are
  8. # met:
  9. # 1. Redistributions in source code must retain the above copyright
  10. #    notice, this list of conditions, and the following disclaimer.
  11. # 2. Redistributions in binary form must reproduce the above copyright
  12. #    notice, this list of conditions, and the following disclaimer in
  13. #    the documentation and/or other materials provided with the
  14. #    distribution.
  15. # 3. Digital Creations requests that attribution be given to Zope
  16. #    in any manner possible. Zope includes a "Powered by Zope"
  17. #    button that is installed by default. While it is not a license
  18. #    violation to remove this button, it is requested that the
  19. #    attribution remain. A significant investment has been put
  20. #    into Zope, and this effort will continue if the Zope community
  21. #    continues to grow. This is one way to assure that growth.
  22. # 4. All advertising materials and documentation mentioning
  23. #    features derived from or use of this software must display
  24. #    the following acknowledgement:
  25. #      "This product includes software developed by Digital Creations
  26. #      for use in the Z Object Publishing Environment
  27. #      (http://www.zope.org/)."
  28. #    In the event that the product being advertised includes an
  29. #    intact Zope distribution (with copyright and license included)
  30. #    then this clause is waived.
  31. # 5. Names associated with Zope or Digital Creations must not be used to
  32. #    endorse or promote products derived from this software without
  33. #    prior written permission from Digital Creations.
  34. # 6. Modified redistributions of any form whatsoever must retain
  35. #    the following acknowledgment:
  36. #      "This product includes software developed by Digital Creations
  37. #      for use in the Z Object Publishing Environment
  38. #      (http://www.zope.org/)."
  39. #    Intact (re-)distributions of any official Zope release do not
  40. #    require an external acknowledgement.
  41. # 7. Modifications are encouraged but must be packaged separately as
  42. #    patches to official Zope releases.  Distributions that do not
  43. #    clearly separate the patches from the original work must be clearly
  44. #    labeled as unofficial distributions.  Modifications which do not
  45. #    carry the name Zope may be packaged in any form, as long as they
  46. #    conform to all of the clauses above.
  47. # Disclaimer
  48. #   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
  49. #   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  50. #   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  51. #   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
  52. #   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  53. #   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  54. #   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  55. #   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  56. #   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  57. #   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  58. #   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  59. #   SUCH DAMAGE.
  60. # This software consists of contributions made by Digital Creations and
  61. # many individuals on behalf of Digital Creations.  Specific
  62. # attributions are listed in the accompanying credits file.
  63. ##############################################################################
  64. __doc__='''Define Zope\'s default security policy
  65.  
  66.  
  67. $Id: ZopeSecurityPolicy.py,v 1.5.8.2 2000/07/05 13:50:41 brian Exp $'''
  68. __version__='$Revision: 1.5.8.2 $'[11:-2]
  69.  
  70. import SimpleObjectPolicies
  71. _noroles=[]
  72.  
  73. from PermissionRole import _what_not_even_god_should_do, rolesForPermissionOn
  74.  
  75.  
  76. class ZopeSecurityPolicy:
  77.     
  78.     def validate(self, accessed, container, name, value, context,
  79.                  None=None, type=type, IntType=type(0), DictType=type({}),
  80.                  getattr=getattr, _noroles=_noroles, StringType=type(''),
  81.                  Containers=SimpleObjectPolicies.Containers,
  82.                  valid_aq_=('aq_parent','aq_explicit')):
  83.  
  84.  
  85.         ############################################################
  86.         # Provide special rules for the acquisition attributes
  87.         if type(name) is StringType:
  88.             if name[:3]=='aq_' and name not in valid_aq_:
  89.                 return 0
  90.  
  91.         containerbase=getattr(container, 'aq_base', container)
  92.         accessedbase=getattr(accessed, 'aq_base', container)
  93.  
  94.         ############################################################
  95.         # Try to get roles
  96.         roles=getattr(value, '__roles__', _noroles)
  97.  
  98.         if roles is _noroles:
  99.  
  100.             ############################################################
  101.             # We have an object without roles. Presumabely, it's
  102.             # some simple object, like a string or a list.
  103.             if container is None: return 0 # Bail if no container
  104.  
  105.             roles=getattr(container, '__roles__', _noroles)
  106.             if roles is _noroles:
  107.                 aq=getattr(container, 'aq_acquire', None)
  108.                 if aq is None:
  109.                     roles=_noroles
  110.                     if containerbase is not accessedbase: return 0
  111.                 else:
  112.                     # Try to acquire roles
  113.                     try: roles=aq('__roles__')
  114.                     except AttributeError:
  115.                         roles=_noroles
  116.                         if containerbase is not accessedbase: return 0
  117.  
  118.             # We need to make sure that we are allowed to
  119.             # get unprotected attributes from the container. We are
  120.             # allowed for certain simple containers and if the
  121.             # container says we can. Simple containers
  122.             # may also impose name restrictions.
  123.             p=Containers(type(container), None)
  124.             if p is None:
  125.                 p=getattr(container,
  126.                           '__allow_access_to_unprotected_subobjects__', None)
  127.  
  128.             if p is not None:
  129.                 tp=type(p)
  130.                 if tp is not IntType:
  131.                     if tp is DictType:
  132.                         p=p.get(name, None)
  133.                     else:
  134.                         p=p(name, value)
  135.  
  136.             if not p:
  137.                 if (containerbase is accessedbase):
  138.                     raise 'Unauthorized', cleanupName(name, value)
  139.                 else:
  140.                     return 0
  141.                         
  142.             if roles is _noroles: return 1
  143.  
  144.             # We are going to need a security-aware object to pass
  145.             # to allowed(). We'll use the container.
  146.             value=container
  147.  
  148.         # Short-circuit tests if we can:
  149.         if roles is None or 'Anonymous' in roles: return 1
  150.  
  151.         # Check executable security
  152.         stack=context.stack
  153.         if stack:
  154.             eo=stack[-1]
  155.  
  156.             # If the executable had an owner, can it execute?
  157.             owner=eo.getOwner()
  158.             if (owner is not None) and not owner.allowed(value, roles):
  159.                 # We don't want someone to acquire if they can't
  160.                 # get an unacquired!
  161.                 if accessedbase is containerbase:
  162.                     raise 'Unauthorized', (
  163.                         'You are not authorized to access <em>%s</em>.' \
  164.                         % cleanupName(name, value))
  165.                 return 0
  166.  
  167.             # Proxy roles, which are a lot safer now.
  168.             proxy_roles=getattr(eo, '_proxy_roles', None)
  169.             if proxy_roles:
  170.                 for r in proxy_roles:
  171.                     if r in roles: return 1
  172.                     
  173.                 # Proxy roles actually limit access!
  174.                 if accessedbase is containerbase:
  175.                     raise 'Unauthorized', (
  176.                         'You are not authorized to access <em>%s</em>.' \
  177.                         % cleanupName(name, value))
  178.                 
  179.                 return 0
  180.                 
  181.  
  182.         try:
  183.             if context.user.allowed(value, roles): return 1
  184.         except AttributeError: pass
  185.  
  186.         # We don't want someone to acquire if they can't get an unacquired!
  187.         if accessedbase is containerbase:
  188.             raise 'Unauthorized', (
  189.                 'You are not authorized to access <em>%s</em>.' \
  190.                 % cleanupName(name, value))
  191.  
  192.         return 0
  193.  
  194.     def checkPermission(self, permission, object, context):
  195.         roles=rolesForPermissionOn(permission, object)
  196.         if roles is _what_not_even_god_should_do: return 0
  197.         return context.user.has_role(roles, object)
  198.     
  199.  
  200. def cleanupName(name, value):
  201.     # If name is not available, tries to get it from the value.
  202.     _name = name
  203.     if _name is None and value is not None:
  204.         try: _name = value.id
  205.         except:
  206.             try: _name = value.__name__
  207.             except: pass
  208.         if callable(_name):
  209.             try: _name = _name()
  210.             except: pass
  211.     return _name
  212.